package com.jinzhi.sysxn.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.base.CoreServiceImpl;
import com.jinzhi.common.exception.IFastException;
import com.jinzhi.common.type.EnumErrorCode;
import com.jinzhi.common.utils.*;
import com.jinzhi.jzweb.pojo.ErrorCodeVo;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import com.jinzhi.sys.dao.UserDao;
import com.jinzhi.sys.domain.RoleDO;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.domain.UserRoleDO;
import com.jinzhi.sys.service.RoleService;
import com.jinzhi.sys.service.UserRoleService;
import com.jinzhi.sysxn.domain.UserExportRequest;
import com.jinzhi.sysxn.service.UserXnService;
import com.jinzhi.sysxn.vo.UserXnExportVO;
import com.jinzhi.sysxn.vo.UserXnImportVO;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author hss
 * @version 1.0
 * @date 2023/12/5 16:43
 */
@Transactional
@Service("sysUserXnServiceImpl")
@AllArgsConstructor
public class UserXnServiceImpl extends CoreServiceImpl<UserDao, UserDO> implements UserXnService {

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    @Override
    public UserDO selectById(Serializable id) {
        UserDO user = baseMapper.selectById(id);
        return user;
    }

    /**
     * 查询用户列表
     * @param userDTO
     * @param page
     * @return
     */
    @Override
    public Page<UserDO> selectPage(UserDO userDTO, Page<UserDO> page) {
        Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>().orderBy("id", false);
        if (userDTO.getName() != null) {
            wrapper.like("name", userDTO.getName());
        }
        if (userDTO.getMobile() != null) {
            wrapper.like("mobile", userDTO.getMobile());
        }
        return super.selectPage(page, wrapper);
    }


    /**
     * 删除用户（将status从1改为0）
     * @param id
     * @return
     */
    @Override
    public Result<String> remove(Long id) {
        Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>();
        wrapper.eq("id", id);
        baseMapper.delete(wrapper);
        return Result.ok();
    }

    /**
     * 修改学号/工号
     * @param user
     * @return
     */
    public Result<String> updateNumber(UserDO user){
        baseMapper.update(user,new EntityWrapper<UserDO>().eq("id",user.getId()));
        return Result.ok();
    };

    /**
     * 修改手机号
     * @param user
     * @return
     */
    public Result<String> updateMobile(UserDO user){

        // 获取缓存中的验证码
        String code1 = (String) EhCacheUtil.get(user.getMobile()+"wx");
        // 校验验证码是否正确
        if (!code1.equals(user.getCode())){
            Result.build(EnumErrorCode.userLoginFai1l1.getCode(),EnumErrorCode.userLoginFai1l1.getMsg());
        }
        //查重 手机号唯一
        Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>();
        wrapper.eq("mobile",user.getMobile());
        int i = baseMapper.selectCount(wrapper);
        if(i != 0){
            return Result.fail("手机号已存在");
        }
        baseMapper.update(user,new EntityWrapper<UserDO>().eq("id",user.getId()));
        return Result.ok();
    };

    /**
     * 管理员重置密码
     * @param userXnDO
     * @return
     */
    @Override
    public int adminResetPwd(UserDO userXnDO) {
        UserDO userDO = selectById(userXnDO.getId());
        //账号类型(3教师 4管理员，5学生)
        if ("4".equals(userDO.getType())) {
            throw new IFastException(EnumErrorCode.userUpdatePwd4adminNotAllowed.getCodeStr());
        }

        String salt = UUIDUtils.get();
        String passwd = PasswdUtils.get(userXnDO.getPassword(), salt);
        userDO.setSalt(salt);
        userDO.setPassword(passwd);
        userDO.setGmtModified(new Date());

        return baseMapper.update(userDO,new EntityWrapper<UserDO>().eq("id",userXnDO.getId()));

    }


    /**
     * 新增一个用户
     * @param userXnDO
     * @return
     */
    @Override
    public Result<String> addUser(UserDO userXnDO){
        //查重 手机号唯一
        Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>();
        wrapper.eq("mobile",userXnDO.getMobile());
        int i = baseMapper.selectCount(wrapper);
            if(i != 0){
            return Result.fail("手机号已存在");
        }

        //密码加密
        String salt = UUIDUtils.get();
        //密码默认为123456
        String encodePasswd = PasswdUtils.get("123456", salt);
        userXnDO.setSalt(salt);
        userXnDO.setPassword(encodePasswd);
        userXnDO.setStatus(1);
        userXnDO.setGmtCreate(new Date());
        userXnDO.setUsername(userXnDO.getMobile());
        baseMapper.insert(userXnDO);

        //添加权限
        Wrapper<RoleDO> wrapper1 = new EntityWrapper<RoleDO>();
        if(userXnDO.getType()==3){
            wrapper1.eq("roleName","教师");
        }else if(userXnDO.getType()==4){
            wrapper1.eq("roleName","管理员");
        }else if(userXnDO.getType()==5){
            wrapper1.eq("roleName","学生");
        }
        RoleDO roleDO = roleService.selectOne(wrapper1);
        UserDO userDO = this.selectOne(wrapper);

        UserRoleDO userRoleDO = new UserRoleDO();
        userRoleDO.setRoleId(roleDO.getId());
        userRoleDO.setUserId(userDO.getId());
        userRoleService.insert(userRoleDO);

        return Result.ok();
    }

    /**
     * 管理员编辑用户
     * @param userXnDO
     * @return
     */
    @Override
    public Result<String> update(UserDO userXnDO) {

        UserDO user = baseMapper.selectById(userXnDO.getId());
        if (user == null){
            return Result.fail();
        }
        //手机号查重
        if(!userXnDO.getMobile().equals(user.getMobile())) {
            Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>();
            wrapper.eq("mobile", userXnDO.getMobile());
            int i = baseMapper.selectCount(wrapper);
            if (i != 0) {
                return Result.fail("手机号已存在");
            }
        }
        user.setName(userXnDO.getName());
        user.setUsername(userXnDO.getMobile());
        user.setMobile(userXnDO.getMobile());
        user.setStudentId(userXnDO.getStudentId());
        user.setCollege(userXnDO.getCollege());
        user.setMajor(userXnDO.getMajor());
        user.setGrade(userXnDO.getGrade());
        user.setAdministrativeClass(userXnDO.getAdministrativeClass());
        user.setType(userXnDO.getType());

        user.setStatus(1);
        user.setGmtModified(new Date());
        baseMapper.updateById(user);

        //修改权限
        Wrapper<RoleDO> wrapper1 = new EntityWrapper<RoleDO>();
        if(userXnDO.getType()==3){
            wrapper1.eq("roleName","教师");
        }else if(userXnDO.getType()==4){
            wrapper1.eq("roleName","管理员");
        }else if(userXnDO.getType()==5){
            wrapper1.eq("roleName","学生");
        }
        RoleDO roleDO = roleService.selectOne(wrapper1);
        UserRoleDO userRoleDO = new UserRoleDO();
        userRoleDO.setRoleId(roleDO.getId());
        Wrapper<UserRoleDO> wrapper2 = new EntityWrapper<UserRoleDO>();
        wrapper2.eq("userId",userXnDO.getId());
        userRoleService.update(userRoleDO,wrapper2);

        return Result.ok();
    }

    /**
     * 用户导出信息
     */
    @Override
    public List<UserXnExportVO> downloadUserXn(UserExportRequest userExportRequest) {
        List<UserDO> list =new LinkedList<UserDO>();
        //code=1则导出全部用户
        if(userExportRequest.getCode()!=null&&userExportRequest.getCode().equals("1")){
            Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>().orderBy("id", false);
            list = this.selectList(wrapper);
        }else {
            if(userExportRequest.getIdList()!=null && !userExportRequest.getIdList().isEmpty()) {
                list = this.selectBatchIds(userExportRequest.getIdList());
            }
        }
        List<UserXnExportVO> list1 = new LinkedList<>();
        for(UserDO li:list){
            UserXnExportVO userXnImportVO=new UserXnExportVO();
            userXnImportVO.setStudentId(li.getStudentId());
            userXnImportVO.setAdministrativeClass(li.getAdministrativeClass());
            userXnImportVO.setCollege(li.getCollege());
            //格式化时间
            if(li.getGmtCreate()!=null) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String str = sdf.format(li.getGmtCreate());
                userXnImportVO.setGmtCreate(str);
            }
            userXnImportVO.setGrade(li.getGrade());
            userXnImportVO.setMobile(li.getMobile());
            userXnImportVO.setName(li.getName());
            userXnImportVO.setMajor(li.getMajor());
            //账号类型(3教师 4管理员，5学生)
            if (li.getType()==3){
                userXnImportVO.setType("教师");
            }else if(li.getType()==4){
                userXnImportVO.setType("管理员");
            }else if(li.getType()==5){
                userXnImportVO.setType("学生");
            }
            list1.add(userXnImportVO);
        }
        return list1;
    }

    /**
     * 导入用户
     * @return
     */
    @Override
    public Result<?> importExcel(MultipartFile file,Long userId) {

        //第一步--判断文件格式
        if (!"application/vnd.ms-excel".equals(file.getContentType())) {
            return Result.fail("文件格式错误，请选择.xls文件");
        }

        //第二步--解析文件获得数据
        List<UserXnImportVO> list = EasyPoiUtil.importExcel(file, 1, 1, UserXnImportVO.class);
        if (list.size() == 0) {
            return Result.fail("Excel数据为空，请完善");
        }

        List<UserDO> upDOList = new ArrayList<>();
        //数据该市行为第三行，第一行标题，第二行表头
        int startRow = 3;
        //错误信息计数
        int cout = 1;
        //错误信息
        List<ErrorCodeVo> list1 = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            StringBuilder sb = new StringBuilder();
            if(list.get(i).getType()==null){
                sb.append("第" + (i + startRow) + "行用户类型未填！" + ";");
            }else if(list.get(i).getType()!=3 && list.get(i).getType()!=4 && list.get(i).getType()!=5){
                sb.append("第" + (i + startRow) + "行用户类型错误！" + ";");
            }
            if(list.get(i).getMobile()==null){
                sb.append("第" + (i + startRow) + "行手机号未填！" + ";");
            }else if(ValidUtils.isMobile(list.get(i).getMobile())) {
                //表格自身手机号查重
                for (int j = 0; j < list.size(); j++) {
                    if (i != j) {
                        if(list.get(j).getMobile()!=null) {
                            if (list.get(i).getMobile().equals(list.get(j).getMobile())) {
                                sb.append("第" + (i + startRow) + "行跟第" + (j + startRow) + "手机号重复，重复值：" + list.get(i).getMobile() + ";");
                            }
                        }
                    }
                }
            }else{
                sb.append("第" + (i + startRow) + "行手机号格式不正确！" + ";");
            }

            //查重 手机号唯一
            Wrapper<UserDO> wrapper = new EntityWrapper<UserDO>();
            wrapper.eq("mobile",list.get(i).getMobile());
            int num = baseMapper.selectCount(wrapper);
            if(num != 0){
                sb.append("第" + (i + startRow) + "行手机号已存在！" + ";");
            }

            if (sb.length() > 0) {
                ErrorCodeVo errorCodeVo = new ErrorCodeVo();
                errorCodeVo.setSeq(cout);
                cout += 1;
                errorCodeVo.setErrorCode(sb.toString());
                list1.add(errorCodeVo);
            }else{
                UserDO userXnDO = new UserDO();
                userXnDO.setGmtCreate(new Date());
                userXnDO.setStatus(1);
                userXnDO.setType(list.get(i).getType());
                userXnDO.setAdministrativeClass(list.get(i).getAdministrativeClass());
                userXnDO.setCollege(list.get(i).getCollege());
                userXnDO.setGrade(list.get(i).getGrade());
                userXnDO.setMobile(list.get(i).getMobile());
                userXnDO.setName(list.get(i).getName());
                userXnDO.setUsername(list.get(i).getMobile());
                userXnDO.setMajor(list.get(i).getMajor());
                userXnDO.setStudentId(list.get(i).getStudentId());

                String salt = UUIDUtils.get();
                String encodePasswd = PasswdUtils.get("123456", salt);
                userXnDO.setSalt(salt);
                userXnDO.setPassword(encodePasswd);
                userXnDO.setStatus(1);

                upDOList.add(userXnDO);
            }
        }

        if (list1.size() == 0) {
            boolean c = this.insertBatch(upDOList, upDOList.size());
            if (c) {
                //添加权限
                for (int i = 0; i <upDOList.size() ; i++) {
                    Wrapper<RoleDO> wrapper1 = new EntityWrapper<RoleDO>();
                    if(upDOList.get(i).getType()==3){
                        wrapper1.eq("roleName","教师");
                    }else if(upDOList.get(i).getType()==4){
                        wrapper1.eq("roleName","管理员");
                    }else if(upDOList.get(i).getType()==5){
                        wrapper1.eq("roleName","学生");
                    }
                    RoleDO roleDO = roleService.selectOne(wrapper1);
                    Wrapper<UserDO> wrapper2 = new EntityWrapper<UserDO>();
                    wrapper2.eq("mobile",upDOList.get(i).getMobile());
                    UserDO userDO = this.selectOne(wrapper2);

                    UserRoleDO userRoleDO = new UserRoleDO();
                    userRoleDO.setRoleId(roleDO.getId());
                    userRoleDO.setUserId(userDO.getId());
                    userRoleService.insert(userRoleDO);
                }

                return Result.ok("成功导入" + list.size() + "条数据");
            } else {
                return Result.fail("报名信息导入错误，请稍后重试或联系管理员");
            }

        } else {
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list1));
            //将list1存到缓存中
            EhCacheUtil.put("userImport" + userId, jsonArray);
            return Result.build(EnumErrorCode.FileImportError.getCode(), EnumErrorCode.FileImportError.getMsg());
        }
    }


}
